﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace GeneticAlgorithm
{
	class Selection
	{
		static Random RD = new Random();

		// 품질 비례 풀렛휠 선택
		// rndm: 랜덤 SEED 지정
		// FT  : Hashtable FTNS
		// <RESUTL>: 풀렛휠을 통해 선택된 값 반환
		public static int RouletteWheelSelection( int rndm, Hashtable FT )
		{
			IDictionaryEnumerator EM = FT.GetEnumerator();

			RD = new Random( DateTime.Now.Millisecond + rndm);

			int jump = 0;
			int pint = RD.Next( 0, Define.ARRN );
			double summ = 0.0;
			
			while ( EM.MoveNext() )
			{
				double numb = double.Parse( string.Format( "{0}", EM.Value ) );
				summ +=  numb;

				if ( pint < summ )
					return jump;
				
				jump++;
			}

			return 0;
		}

		// 품질 비례 룰렛휠을 위해 공간 할당
		// FT  : Hashtable FTNS
		// <Result>: 룰렛휠 상에 자신의 적합도 만큼의 공간을 재배정
		public static void EvaluateBestFitness( Hashtable FT )
		{
			IDictionaryEnumerator EM = FT.GetEnumerator();

			double	rslt = 0.0;
			int		skey = 0;

			while ( EM.MoveNext() )
			{
				double numb = double.Parse( string.Format( "{0}", EM.Value ) );
				rslt = CalculateFitness( numb );
				GA.BSFT.Add( skey, rslt.ToString() );

				skey++;
			}
		}

		// 품질 비례 룰렛휠 선택
		// 우수한 해와 열등한 해의 선택될 확률 조절
		// 각 해의 품질을 평가한 다음 가장 좋은 해의 적합도가 나븐 해의 적합도의 2배가 되도로 조절
		// FT  : Hashtable FTNS
		// <Result>: 각 해의 적합도 조절
		public static double CalculateFitness( double numb )
		{
			return ( numb - Define.FTMN ) + ( Define.FTMX - Define.FTMN ) / 2;
		}

		// 적합도 총합
		// FT  : Hashtable FTNS
		// <Result>: 적합도 총합 반환
		public static double EvaluateFitnessTotal( Hashtable FT )
		{
			double rslt = 0.0;
			IDictionaryEnumerator EM = FT.GetEnumerator();

			while ( EM.MoveNext() )
			{
				double numb = double.Parse( string.Format( "{0}", EM.Value ) );
				rslt += numb;
			}

			return rslt;
		}

		// 적합도 백분율 계산
		// FT  : Hashtable FTNS
		// <Result>: 각 해의 적합도 백분율 지정
		public static void EvaluateFitnessRadio( Hashtable FT )
		{
			IDictionaryEnumerator EF = FT.GetEnumerator();

			double rslt = 0.0;
			double fttl = EvaluateFitnessTotal( GA.FTNS );

			int skex = 0;

			while ( EF.MoveNext() )
			{
				double numb = double.Parse( string.Format( "{0}", EF.Value ) );
				rslt = numb / fttl;
				GA.RLTT.Add ( skex, rslt.ToString() );
				skex++;
			}
		}
	}
}
